package com.sxhuayuan.parking.service.impl;

import com.sxhuayuan.parking.compenent.Filter;
import com.sxhuayuan.parking.compenent.Page;
import com.sxhuayuan.parking.compenent.Pageable;
import com.sxhuayuan.parking.dao.BaseDao;
import com.sxhuayuan.parking.dao.ProfitStatisticsDao;
import com.sxhuayuan.parking.entity.Agent;
import com.sxhuayuan.parking.entity.MonthlyProfit;
import com.sxhuayuan.parking.entity.ProfitStatistics;
import com.sxhuayuan.parking.service.ProfitStatisticsService;
import com.sxhuayuan.parking.utils.DateUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.persistence.Query;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * 代理分润统计实现类
 * 
 * @author 何龙
 * @create 2019-04-25 14:10
 */
@Service("profitStatisticsServiceImpl")
public class ProfitStatisticsServiceImpl extends BaseServiceImpl<ProfitStatistics, Long> implements ProfitStatisticsService {

	@Resource
	ProfitStatisticsDao dao;

	@Override
	public BaseDao<ProfitStatistics, Long> getDAO() {
		return dao;
	}

	@Override
	public ProfitStatistics findByAgentAndDate(Agent agent, LocalDate date) {
		return dao.findByAgentAndStatistisDate(agent, date);
	}

	@Override
	public Page<ProfitStatistics> findPage(Pageable pageable, Agent agent) {
		StringBuilder sb = new StringBuilder("select p from ProfitStatistics p ");

		if (agent != null && agent.getId() != null) {
			sb.append("join AgentRelation r on p.agent=r.child where r.parent.id=").append(agent.getId()).append(" ");
		} else {
			sb.append("where 1=1 ");
		}
		List<Filter> filters = pageable.getFilters();
		if (filters != null) {
			for (Filter filter : filters) {
				sb = setCondition(sb, filter);
			}
		}
		sb.append(" order by p.statistisDate desc");

		return findPage(sb.toString(), sb.toString().replace("select p", "select count(p.id)"), pageable.getPageSize(), pageable.getPageNumber());

	}

	@Override
	public BigDecimal[] sumByPage(Pageable pageable, Agent agent) {
		BigDecimal[] bigDecimals = new BigDecimal[3];
		StringBuilder sb = new StringBuilder("select sum(p.totalProfit),sum(p.weixinProfit),sum(p.alipayProfit) from ProfitStatistics p ");

		if (agent != null && agent.getId() != null) {
			sb.append("join AgentRelation r on p.agent=r.child where r.parent.id=").append(agent.getId()).append(" ");
		} else {
			sb.append("where 1=1 ");
		}
		List<Filter> filters = pageable.getFilters();
		if (filters != null) {
			for (Filter filter : filters) {
				sb = setCondition(sb, filter);
			}
		}

		Query query = entityManager.createQuery(sb.toString());
		List resultList = query.getResultList();
		if (resultList.size() > 0) {
			Object[] o = (Object[]) resultList.get(0);
			bigDecimals[0] = o[0] == null ? BigDecimal.ZERO : (BigDecimal) o[0];
			bigDecimals[1] = o[1] == null ? BigDecimal.ZERO : (BigDecimal) o[1];
			bigDecimals[2] = o[2] == null ? BigDecimal.ZERO : (BigDecimal) o[2];
		} else {
			bigDecimals[0] = BigDecimal.ZERO;
			bigDecimals[1] = BigDecimal.ZERO;
			bigDecimals[2] = BigDecimal.ZERO;
		}

		return bigDecimals;
	}

	@Override
	public MonthlyProfit countByAgentAndMonth(Agent agent, LocalDate date) {

		String month = date.format(DateTimeFormatter.ofPattern("yyyy-MM"));
		List<Object> objects = dao.countMonthlyProfitByAgentAndMonth(agent.getId(), month);
		MonthlyProfit mp = new MonthlyProfit();
		mp.setAgent(agent);
		mp.setStatistisMonth(date);
		if (objects.size() > 0) {
			Object[] list = (Object[]) objects.get(0);
			mp.setTotalMoney((BigDecimal) list[0]);
			mp.setTotalCount(list[1] == null ? 0L : ((BigDecimal) list[1]).longValue());
			mp.setWeixinMoney((BigDecimal) list[2]);
			mp.setWeixinCount(list[3] == null ? 0L : ((BigDecimal) list[3]).longValue());
			mp.setAlipayMoney((BigDecimal) list[4]);
			mp.setAlipayCount(list[5] == null ? 0L : ((BigDecimal) list[5]).longValue());
			mp.setTotalProfit((BigDecimal) list[6]);
			mp.setWeixinProfit((BigDecimal) list[7]);
			mp.setAlipayProfit((BigDecimal) list[8]);
			mp.setTotalOriginalProfit((BigDecimal) list[9]);
			mp.setWeixinOriginalProfit((BigDecimal) list[10]);
			mp.setAlipayOriginalProfit((BigDecimal) list[11]);
		}
		return mp;
	}

	@Override
	public List<ProfitStatistics> findByAgentAndMonth(Agent agent, LocalDate month) {
		LocalDate minDate = DateUtils.getMinDate(month);
		LocalDate maxDate = DateUtils.getMaxDate(minDate);
		return dao.findByAgentAndMonth(agent,minDate,maxDate);
	}

	private StringBuilder setCondition(StringBuilder sb, Filter filter) {
		if (filter.getProperty() == null || filter.getProperty().equals("") || filter.getValue() == null || filter.getValue().equals("")) {
			return sb;
		}
		switch (filter.getProperty()) {

		case "istartTime": {
			return sb.append(" and p.statistisDate>='").append(filter.getValue()).append("' ");
		}
		case "iendTime": {
			return sb.append(" and p.statistisDate<='").append(filter.getValue()).append("' ");
		}
		case "agentName": {
			return sb.append(" and p.agent.name='").append(filter.getValue()).append("' ");
		}
		case "parentAgentName": {
			return sb.append(" and m.agent.parent.name='").append(filter.getValue()).append("' ");
		}
		case "level": {
			Integer level = (Integer) filter.getValue();
			if (level == -1) {
				return sb.append(" and  p.agent.parent is null ");
			} else if (level == -2) {
				return sb.append(" and r.level!=0 ");
			} else if (level >= 0) {
				return sb.append(" and r.level=").append(level).append(" ");
			} else {
				return sb;
			}
		}
		default:
			return sb;
		}
	}

	/**
	 * 新增代理分润统计
	 * 
	 * @param profitStatistics
	 */
	@Override
	@Transactional
	public void save(ProfitStatistics profitStatistics) {
		// 昨天
		LocalDate localDate = LocalDate.now().minusDays(1);

		// 保证每天每个代理的分润统计只有一条
		List<ProfitStatistics> list = dao.findByAgentAndToday(profitStatistics.getAgent(), localDate);
		if (list.size() > 0) {
			for (ProfitStatistics statistics : list) {
				dao.delete(statistics);
			}
		}
		dao.save(profitStatistics);
	}
}
